import { useEffect, useRef, useCallback, forwardRef, useImperativeHandle } from 'react';
// @ts-ignore
import { fabric } from 'fabric';

interface FabricCanvasProps {
  images: any[];
  onImagesChange: (images: any[]) => void;
  activeTool: string;
  onImageSelect: (imageId: string) => void;
  onLayersChange?: () => void; // 新增图层变化回调
  width?: number; // 画布宽度
  height?: number; // 画布高度
  brushColor?: string; // 画笔颜色
  brushWidth?: number; // 画笔宽度
}

const FabricCanvas = forwardRef<any, FabricCanvasProps>(({
  images,
  onImagesChange,
  activeTool,
  onImageSelect,
  onLayersChange,
  width,
  height,
  brushColor = '#00cae0',
  brushWidth = 2
}, ref) => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const fabricCanvasRef = useRef<fabric.Canvas | null>(null);

  // 初始化 Fabric.js 画布
  useEffect(() => {
    if (canvasRef.current && !fabricCanvasRef.current) {
      // 计算画布尺寸，优先使用传入的参数，否则使用默认值
      const canvasWidth = width || (window.innerWidth - 200);
      const canvasHeight = height || (window.innerHeight - 100);
      
      fabricCanvasRef.current = new fabric.Canvas(canvasRef.current, {
        width: canvasWidth,
        height: canvasHeight,
        backgroundColor: 'transparent',
        selection: activeTool === 'select'
      });

      // 设置画笔
      fabricCanvasRef.current.freeDrawingBrush = new fabric.PencilBrush(fabricCanvasRef.current);
      fabricCanvasRef.current.freeDrawingBrush.width = brushWidth;
      fabricCanvasRef.current.freeDrawingBrush.color = brushColor;

      // 监听选择事件
      fabricCanvasRef.current.on('selection:created', (e: any) => {
        if (e.selected && e.selected.length > 0) {
          const selectedObject = e.selected[0];
          if (selectedObject.name) {
            onImageSelect(selectedObject.name);
          }
        }
      });

      // 监听对象修改事件
      fabricCanvasRef.current.on('object:modified', () => {
        updateImagesFromCanvas();
        onLayersChange?.();
      });

      // 监听对象移动事件
      fabricCanvasRef.current.on('object:moving', () => {
        updateImagesFromCanvas();
        onLayersChange?.();
      });

      // 监听对象缩放事件
      fabricCanvasRef.current.on('object:scaling', () => {
        updateImagesFromCanvas();
        onLayersChange?.();
      });

      // 监听对象旋转事件
      fabricCanvasRef.current.on('object:rotating', () => {
        updateImagesFromCanvas();
        onLayersChange?.();
      });

      // 监听对象添加事件
      fabricCanvasRef.current.on('object:added', () => {
        updateImagesFromCanvas();
        onLayersChange?.();
      });

      // 监听对象删除事件
      fabricCanvasRef.current.on('object:removed', () => {
        updateImagesFromCanvas();
        onLayersChange?.();
      });
    }

    return () => {
      if (fabricCanvasRef.current) {
        fabricCanvasRef.current.dispose();
        fabricCanvasRef.current = null;
      }
    };
  }, []);

  // 处理画布尺寸变化
  useEffect(() => {
    if (fabricCanvasRef.current && (width || height)) {
      const canvasWidth = width || fabricCanvasRef.current.getWidth();
      const canvasHeight = height || fabricCanvasRef.current.getHeight();
      
      fabricCanvasRef.current.setDimensions({
        width: canvasWidth,
        height: canvasHeight
      });
    }
  }, [width, height]);

  // 从画布更新图片数据
  const updateImagesFromCanvas = useCallback(() => {
    if (!fabricCanvasRef.current) return;

        const canvasObjects = fabricCanvasRef.current.getObjects();
        const updatedImages = canvasObjects
          .filter((obj: any) => obj.type === 'image' && obj.name)
          .map((obj: any) => {
            const fabricImage = obj as fabric.Image;
        return {
          id: obj.name!,
          src: (fabricImage.getElement() as HTMLImageElement).src,
          x: obj.left || 0,
          y: obj.top || 0,
          width: (obj.width || 0) * (obj.scaleX || 1),
          height: (obj.height || 0) * (obj.scaleY || 1),
          rotation: obj.angle || 0,
          scale: obj.scaleX || 1,
          selected: obj === fabricCanvasRef.current!.getActiveObject()
        };
      });

    onImagesChange(updatedImages);
  }, [onImagesChange]);

  // 同步图片到画布
  useEffect(() => {
    if (!fabricCanvasRef.current) return;

    const canvas = fabricCanvasRef.current;
    const currentObjects = canvas.getObjects();
    
    // 移除不存在的图片
    currentObjects.forEach((obj: any) => {
      if (obj.type === 'image' && obj.name) {
        const exists = images.some(img => img.id === obj.name);
        if (!exists) {
          canvas.remove(obj);
        }
      }
    });

    // 添加或更新图片
    images.forEach(imageData => {
      const existingObject = canvas.getObjects().find((obj: any) => 
        obj.type === 'image' && obj.name === imageData.id
      );

      if (existingObject) {
        // 更新现有对象
        existingObject.set({
          left: imageData.x,
          top: imageData.y,
          angle: imageData.rotation,
          scaleX: imageData.scale,
          scaleY: imageData.scale
        });
        existingObject.setCoords();
      } else {
        // 创建新图片对象
        fabric.Image.fromURL(imageData.src, (img: any) => {
          if (img) {
            const canvasWidth = canvas.getWidth();
            const canvasHeight = canvas.getHeight();
            
            // 如果图片数据中没有位置信息，则让图片占满画布
            if (imageData.x === 0 && imageData.y === 0 && imageData.scale === 1) {
              // 计算图片缩放比例，高度占满宽度自适应
              const scale = canvasHeight / img.height; // 以高度为准进行缩放
              
              // 计算居中位置
              const scaledWidth = img.width * scale;
              const scaledHeight = img.height * scale;
              const left = (canvasWidth - scaledWidth) / 2;
              const top = (canvasHeight - scaledHeight) / 2;
              
              img.set({
                left: left,
                top: top,
                scaleX: scale,
                scaleY: scale,
                name: imageData.id,
                selectable: true,
                evented: true
              });
            } else {
              // 使用传入的位置和缩放信息
              img.set({
                left: imageData.x,
                top: imageData.y,
                angle: imageData.rotation,
                scaleX: imageData.scale,
                scaleY: imageData.scale,
                name: imageData.id,
                selectable: true,
                evented: true
              });
            }
            
            canvas.add(img);
            canvas.renderAll();
          }
        });
      }
    });
  }, [images]);

  // 设置工具
  useEffect(() => {
    if (!fabricCanvasRef.current) return;

    const canvas = fabricCanvasRef.current;
    
    switch (activeTool) {
      case 'select':
        canvas.isDrawingMode = false;
        canvas.selection = true;
        break;
      case 'brush':
        canvas.isDrawingMode = true;
        canvas.selection = false;
        break;
      case 'erase':
        canvas.isDrawingMode = true;
        canvas.selection = false;
        break;
      case 'crop':
        canvas.isDrawingMode = false;
        canvas.selection = true;
        break;
    }
  }, [activeTool]);

  // 更新画笔设置
  useEffect(() => {
    if (!fabricCanvasRef.current) return;

    const canvas = fabricCanvasRef.current;
    if (canvas.freeDrawingBrush) {
      canvas.freeDrawingBrush.width = brushWidth;
      canvas.freeDrawingBrush.color = brushColor;
    }
  }, [brushColor, brushWidth]);

  // 处理文件上传
  const handleFileUpload = useCallback(async (files: FileList) => {
    if (!fabricCanvasRef.current) return;

    const loadPromises = Array.from(files).map((file) => {
      if (file.type.startsWith('image/')) {
        return new Promise<void>((resolve) => {
          const reader = new FileReader();
          reader.onload = (e) => {
            const img = new Image();
            img.onload = () => {
              const canvas = fabricCanvasRef.current!;
              const canvasWidth = canvas.getWidth();
              const canvasHeight = canvas.getHeight();
              
              // 计算图片缩放比例，高度占满宽度自适应
              const scale = canvasHeight / img.height; // 以高度为准进行缩放
              
              // 计算居中位置
              const scaledWidth = img.width * scale;
              const scaledHeight = img.height * scale;
              const left = (canvasWidth - scaledWidth) / 2;
              const top = (canvasHeight - scaledHeight) / 2;
              
              const fabricImage = new fabric.Image(img, {
                left: left,
                top: top,
                scaleX: scale,
                scaleY: scale,
                name: Date.now().toString(),
                selectable: true,
                evented: true
              });
              
              canvas.add(fabricImage);
              canvas.renderAll();
              
              // 图片加载完成后更新状态
              updateImagesFromCanvas();
              onLayersChange?.();
              
              resolve();
            };
            img.src = e.target?.result as string;
          };
          reader.readAsDataURL(file);
        });
      }
      return Promise.resolve();
    });

    // 等待所有图片加载完成
    await Promise.all(loadPromises);
  }, [updateImagesFromCanvas, onLayersChange]);

  // 删除选中的对象
  const deleteSelected = useCallback(() => {
    if (!fabricCanvasRef.current) return;
    
    const activeObjects = fabricCanvasRef.current.getActiveObjects();
    activeObjects.forEach((obj: any) => {
      fabricCanvasRef.current!.remove(obj);
    });
    fabricCanvasRef.current!.discardActiveObject();
    fabricCanvasRef.current!.renderAll();
  }, []);

  // 旋转选中的对象
  const rotateSelected = useCallback(() => {
    if (!fabricCanvasRef.current) return;
    
    const activeObject = fabricCanvasRef.current.getActiveObject();
    if (activeObject) {
      activeObject.rotate(activeObject.angle + 90);
      fabricCanvasRef.current!.renderAll();
    }
  }, []);

  // 缩放选中的对象
  const scaleSelected = useCallback((scaleDelta: number) => {
    if (!fabricCanvasRef.current) return;
    
    const activeObject = fabricCanvasRef.current.getActiveObject();
    if (activeObject) {
      const newScale = Math.max(0.1, Math.min(3, (activeObject.scaleX || 1) + scaleDelta));
      activeObject.scale(newScale);
      fabricCanvasRef.current!.renderAll();
    }
  }, []);

  // 暴露方法给父组件
  useImperativeHandle(ref, () => ({
    handleFileUpload,
    deleteSelected,
    rotateSelected,
    scaleSelected,
    // 暴露 Fabric.js 画布实例
    getCanvas: () => fabricCanvasRef.current,
    // 暴露常用方法
    getObjects: () => fabricCanvasRef.current?.getObjects() || [],
    toDataURL: (options?: any) => fabricCanvasRef.current?.toDataURL(options),
    clear: () => {
      if (fabricCanvasRef.current) {
        const objects = fabricCanvasRef.current.getObjects();
        objects.forEach((obj: any) => {
          fabricCanvasRef.current!.remove(obj);
        });
        fabricCanvasRef.current.renderAll();
      }
    }
  }), [handleFileUpload, deleteSelected, rotateSelected, scaleSelected]);

  return (
    <div className="fabric-canvas-container">
      <canvas ref={canvasRef} />
    </div>
  );
});

FabricCanvas.displayName = 'FabricCanvas';

export default FabricCanvas;
